/*******************************************************************************
 *
 *	:  IO
 *
 *******************************************************************************/
#define PORT_PIN_CTEAT
#include "bsp.h"
#include "bsp_io.h"
#include "iohandle.h"
#include "pincfg.h"
#include "mytype.h"

void bsp_pin_mux_cfg(uint32_t gpio_x, uint32_t pin, uint32_t gpio_mux);

/*******************************************************************************
 * @brief  gpio cfg list
 *******************************************************************************/
static gpio_init_cfg_type gpio_cfg[] = {
	// U0
	{GPIOA, GPIO_MODE_AF, GPIO_OSPEED_50MHZ, GPIO_OTYPE_PP, GPIO_PUPD_NONE, GPIO_AF_7, 1, GPIO_PIN_9},
	{GPIOA, GPIO_MODE_AF, GPIO_OSPEED_50MHZ, GPIO_OTYPE_PP, GPIO_PUPD_NONE, GPIO_AF_7, 1, GPIO_PIN_10},

	// SPI: PB12-CS, PB13-SCK, PB14-MISO, PB15-MOSI
	{GPIOB, GPIO_MODE_AF, GPIO_OSPEED_50MHZ, GPIO_OTYPE_PP, GPIO_PUPD_NONE, GPIO_AF_6, 1, GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15},
	{GPIOB, GPIO_MODE_OUTPUT, GPIO_OSPEED_50MHZ, GPIO_OTYPE_PP, GPIO_PUPD_NONE, GPIO_AF_6, 1, GPIO_PIN_12},
};

/*******************************************************************************
 * @brief  bsp_gpio_init
 * \param[in] us delay
 * \retval: none
 *******************************************************************************/
void bsp_gpio_init(void)
{
	int index;

	/*gpio cfg*/
	for (index = 0; index < sizeof(gpio_cfg) / sizeof(gpio_init_cfg_type); index++)
	{
		gpio_mode_set(gpio_cfg[index].port, gpio_cfg[index].mode, gpio_cfg[index].pull, gpio_cfg[index].pin);
		gpio_output_options_set(gpio_cfg[index].port, gpio_cfg[index].out_type, gpio_cfg[index].drive, gpio_cfg[index].pin);
		if(gpio_cfg[index].mode == GPIO_MODE_AF)
		gpio_af_set(gpio_cfg[index].port, gpio_cfg[index].mux, gpio_cfg[index].pin);
		gpio_bit_write(gpio_cfg[index].port, gpio_cfg[index].pin, gpio_cfg[index].val_init);
	}

	led1.dir_out_pp();
	led2.dir_out_pp();
	led3.dir_out_pp();
	led4.dir_out_pp();
	key.dir_in_dn();
}

/*******************************************************************************
 * @brief  bsp_gpio
 * \param[in] us delay
 * \retval: none
 *******************************************************************************/
void bsp_pin_mux_cfg(uint32_t gpio_x, uint32_t pin, uint32_t gpio_mux)
{
	gpio_af_set(gpio_x, gpio_mux, pin);

	/*
	loop(16)
	{
		if ((1UL << index) & pin)
		{
			gpio_pin_mux_config(gpio_x, (gpio_pins_source_type)index, gpio_mux);
		}
	}
	*/
}

/*******************************************************************************
 * @brief  bsp_gpio
 * \param[in] us delay
 * \retval: none
 *******************************************************************************/
void bsp_gpio_mode_out_pp(uint32_t port, uint8_t pin)
{
	intx_alloc();

	intx_disable();

	GPIO_CTL(port) &= ~(3UL << pin * 2);
	GPIO_CTL(port) |= 1UL << pin * 2;
	GPIO_OMODE(port) &= ~(1UL << pin);

	GPIO_OSPD(port) &= ~(0x03UL << pin * 2);
	GPIO_OSPD(port) |= 1UL << 2 * pin;

	intx_enable();
}

void bsp_gpio_mode_out_od(uint32_t port, uint8_t pin)
{
	intx_alloc();

	intx_disable();

	GPIO_CTL(port) &= ~(3UL << pin * 2);
	GPIO_CTL(port) |= 1UL << pin * 2;
	GPIO_OMODE(port) |= 1UL << pin;

	GPIO_OSPD(port) &= ~(3UL << pin * 2);
	GPIO_OSPD(port) |= 1UL << 2 * pin;

	intx_enable();
}

void bsp_gpio_mode_out_pp_spd(uint32_t port, uint8_t pin, uint32_t spd)
{
	intx_alloc();

	intx_disable();

	GPIO_CTL(port) &= ~(3UL << pin * 2);
	GPIO_CTL(port) |= 1UL << pin * 2;
	GPIO_OMODE(port) &= ~(1UL << pin);

	GPIO_OSPD(port) &= ~(0x03UL << pin * 2);
	GPIO_OSPD(port) |= spd << 2 * pin;

	intx_enable();
}

void bsp_gpio_mode_out_od_spd(uint32_t port, uint8_t pin, uint32_t spd)
{
	intx_alloc();

	intx_disable();

	GPIO_CTL(port) &= ~(3UL << pin * 2);
	GPIO_CTL(port) |= 1UL << pin * 2;
	GPIO_OMODE(port) |= 1UL << pin;

	GPIO_OSPD(port) &= ~(3UL << pin * 2);
	GPIO_OSPD(port) |= spd << 2 * pin;

	intx_enable();
}

void bsp_gpio_mode_in_up(uint32_t port, uint8_t pin)
{
	intx_alloc();

	intx_disable();

	GPIO_CTL(port) &= ~(3UL << pin * 2);
	GPIO_PUD(port) &= ~(3UL << pin * 2);
	GPIO_PUD(port) |= 1UL << pin * 2;

	intx_enable();
}

void bsp_gpio_mode_in_dn(uint32_t port, uint8_t pin)
{
	intx_alloc();

	intx_disable();

	GPIO_CTL(port) &= ~(3UL << pin * 2);
	GPIO_PUD(port) &= ~(3UL << pin * 2);
	GPIO_PUD(port) |= 2UL << pin * 2;

	intx_enable();
}

void bsp_gpio_mode_in_ft(uint32_t port, uint8_t pin)
{
	intx_alloc();

	intx_disable();

	GPIO_CTL(port) &= ~(3UL << pin * 2);
	GPIO_PUD(port) &= ~(3UL << pin * 2);

	intx_enable();
}

void bsp_gpio_mode_ain(uint32_t port, uint8_t pin)
{
	intx_alloc();

	intx_disable();

	GPIO_CTL(port) |= 3UL << pin * 2;
	GPIO_PUD(port) &= ~(3UL << pin * 2);

	intx_enable();
}

void bsp_gpio_mode_set(uint32_t port, uint8_t pin, char pm)
{
	switch (pm)
	{
	case PIN_MODE_IN_UP:
	{
		bsp_gpio_mode_in_up(port, pin);
		break;
	}
	case PIN_MODE_IN_DN:
	{
		bsp_gpio_mode_in_dn(port, pin);
		break;
	}
	case PIN_MODE_IN_FLOAT:
	{
		bsp_gpio_mode_in_ft(port, pin);
		break;
	}
	case PIN_MODE_IN_AIN:
	{
		bsp_gpio_mode_ain(port, pin);
		break;
	};
	case PIN_MODE_OUT_SL_PP:
	{
		bsp_gpio_mode_out_pp_spd(port, pin, 2);
		break;
	}
	case PIN_MODE_OUT_SL_OD:
	{
		bsp_gpio_mode_out_od_spd(port, pin, 2);
		break;
	}
	case PIN_MODE_OUT_SM_PP:
	{
		bsp_gpio_mode_out_pp_spd(port, pin, 2);
		break;
	}
	case PIN_MODE_OUT_SM_OD:
	{
		bsp_gpio_mode_out_od_spd(port, pin, 2);
		break;
	}
	case PIN_MODE_OUT_SH_PP:
	{
		bsp_gpio_mode_out_pp_spd(port, pin, 1);
		break;
	}
	case PIN_MODE_OUT_SH_OD:
	{
		bsp_gpio_mode_out_od_spd(port, pin, 1);
		break;
	}
	default:
	{
		break;
	}
	}
}